package com.hst.capacity.application.biz.impl;

import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.qrcode.QrCodeUtil;
import cn.hutool.extra.qrcode.QrConfig;
import com.hst.capacity.application.biz.FleetBiz;
import com.hst.capacity.domain.common.constants.Constants;
import com.hst.capacity.domain.exception.BusinessException;
import com.hst.capacity.domain.model.entity.driver.DriverEntity;
import com.hst.capacity.domain.model.entity.franchisee.FleetEntity;
import com.hst.capacity.domain.model.entity.franchisee.fleet.FleetUserEntity;
import com.hst.capacity.domain.model.entity.setting.commision.FleetCommisionEntity;
import com.hst.capacity.domain.model.request.fleet.*;
import com.hst.capacity.domain.model.response.PagingResultVO;
import com.hst.capacity.domain.model.response.fleet.FleetCommisionSelectVO;
import com.hst.capacity.domain.model.response.fleet.FleetSearchDriverVO;
import com.hst.capacity.domain.model.response.fleet.FleetSearchVO;
import com.hst.capacity.domain.model.response.fleet.FleetUserSearchVO;
import com.hst.capacity.domain.service.FleetService;
import com.hst.capacity.domain.service.UploadService;
import com.hst.capacity.infra.convertor.FleetConvertor;
import com.hst.capacity.infra.persistence.jpa.driver.DriverRepository;
import com.hst.capacity.infra.persistence.jpa.fleet.FleetInforRepository;
import com.hst.capacity.infra.persistence.jpa.fleet.FleetUserRepository;
import com.hst.capacity.infra.persistence.jpa.setting.commision.FleetCommisionRepository;
import com.hst.capacity.infra.persistence.mybatis.FleetMapper;
import com.hst.capacity.infra.util.StringUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import java.awt.*;
import java.time.LocalDateTime;


@Service
public class FleetBizImpl implements FleetBiz {

    @Autowired
    private FleetService fleetService;
    @Autowired
    private UploadService uploadService;

    @Autowired
    private FleetMapper fleetMapper;

    @Autowired
    private FleetInforRepository fleetInforRepository;
    @Autowired
    private FleetUserRepository fleetUserRepository;
    @Autowired
    private DriverRepository driverRepository;
    @Autowired
    private FleetCommisionRepository commisionRepository;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Value("${qrcode.fleet-domain}")
    private String fleetDomain;

    @Override
    public PagingResultVO<FleetUserSearchVO> dispatchAccountSearch(FleetUserSearchParam param) {
        Page<FleetUserEntity> page = fleetUserRepository.findByIdFleet(param.getIdFleet(), PageRequest.of(param.getPageIndex() - 1, param.getPageSize()));
        return new PagingResultVO<>(page.getTotalElements(),FleetConvertor.INSTANCE.convert2LstVO(page.getContent()));
    }

    @Override
    public FleetUserSearchVO dispatchAccountDetail(String idFleetUser) {
        return FleetConvertor.INSTANCE.convert2VO(fleetUserRepository.findByIdFleetUser(idFleetUser));
    }

    @Override
    public String dispatchAccountSave(FleetUserSaveParam param) {

        FleetUserEntity entity;
        LocalDateTime lastLoginTime;
        if (StrUtil.isNotEmpty(param.getIdFleetUser())){
            entity = fleetUserRepository.findById(param.getIdFleetUser()).orElse(null);
            if (entity == null)
                throw new BusinessException(5002,"编辑对象不存在");
            String idFleetUser = entity.getIdFleetUser();
            String password = entity.getPassword();
            lastLoginTime = entity.getLastLoginTime();
            param.setErrorNumber(entity.getErrorNumber());
            entity = FleetConvertor.INSTANCE.convert2Entity(param);
            entity.setIdFleetUser(idFleetUser);
            if (StringUtil.isBlank(param.getPassword()))
                entity.setPassword(password);
            entity.setLastLoginTime(lastLoginTime);
        }else {
            entity = fleetUserRepository.findByMobile(param.getMobile());
            if (entity != null)
                throw new BusinessException(5002,"手机号已经被其他车队注册，请更换手机号注册");
            entity = FleetConvertor.INSTANCE.convert2Entity(param);
            entity.setPassword(passwordEncoder.encode(param.getPassword()));
            entity.setErrorNumber(0);
        }

        //在此处新增一个判断是否生成了二维码的逻辑
        if(StringUtils.isBlank(entity.getInviteImageUrl())){
            String url = fleetDomain + "/driverRegister?fleet=" + entity.getIdFleet();
            QrConfig qrConfig = QrConfig.create();
            qrConfig.setBackColor(Color.WHITE);
            qrConfig.setForeColor(Color.BLACK);
            qrConfig.setWidth(450);
            qrConfig.setHeight(450);
            byte[] bytes = QrCodeUtil.generatePng(url, qrConfig);
            String fileName = "fleet/qrcode/"+entity.getIdFleet() + ".png";
            uploadService.uploadImageByBytes(fileName,bytes);
            entity.setInviteImageUrl(fileName);
        }

        entity = fleetUserRepository.save(entity);
        return entity.getIdFleetUser();
    }

    @Override
    public PagingResultVO<FleetSearchVO> search(FleetSearchParam param) {
        return new PagingResultVO<>(fleetMapper.searchTotal(param), fleetMapper.search(param));
    }

    @Override
    public String save(FleetSaveParam param) {
        boolean isExist = fleetService.checkTel(param);
        if (isExist)
            throw new BusinessException(5002,"联系人电话已被使用，请更换！");
        return fleetService.save(param).getIdFleet();
    }

    @Override
    public FleetSearchVO select(String idFleet) {
        FleetSearchVO re = FleetConvertor.INSTANCE.convertSelect(fleetInforRepository.findById(idFleet).orElse(null));
        if (re==null)throw new BusinessException(5002,"编辑的对象不存在");
        return re;
    }

    @Override
    public PagingResultVO<FleetSearchDriverVO> searchDriverBind(FleetSearchDriverParam param) {
        Page<FleetSearchDriverVO> page = driverRepository.findByIdFleetBand(param.getIdFleet(), PageRequest.of(param.getPageIndex() - 1, param.getPageSize()));
        return new PagingResultVO<>(page.getTotalElements(),page.getContent());
    }

    @Override
    public PagingResultVO<FleetSearchDriverVO> searchUnBindFleetDriver(FleetSearchDriverParam param) {
        return new PagingResultVO<>(fleetMapper.searchDriverTotal(param),fleetMapper.searchDriver(param));
    }

    @Override
    public PagingResultVO<FleetSearchDriverVO> searchDriverMobile(FleetSearchDriverParam param) {
        Page<FleetSearchDriverVO> page = driverRepository.searchDriverMobile(param.getMobile(), param.getIdFranchisee(), param.getIdAgent(), PageRequest.of(param.getPageIndex() - 1, param.getPageSize()));
        return new PagingResultVO<>(page.getTotalElements(),page.getContent());
    }

    @Override
    public int fleetCount(String idFranchisee) {
        return fleetInforRepository.getFleetCountByFran(idFranchisee);
    }

    @Override
    public Boolean statusOpen(FleetStatusParam param) {
        return this.statusToggle(param, Constants.AccountStatus.NORMAL);
    }

    @Override
    public Boolean statusFreeze(FleetStatusParam param) {
        return this.statusToggle(param, Constants.AccountStatus.FREEZE);
    }

    private boolean statusToggle(FleetStatusParam param, int status) {
        FleetEntity entity = fleetInforRepository.findById(param.getIdFleet()).get();
        if (entity == null) {
            throw new BusinessException(5002, "编辑对象不存在");
        } else {
            if (entity.getIdFranchisee() == null) {
                entity.setIdFranchisee(param.getIdFranchisee());
            } else if (entity.getIdFranchisee() != null &&
                    !entity.getIdFranchisee().equals(param.getIdFranchisee())) {
                if (StringUtil.isBlank(entity.getIdFranchisee())) {
                    entity.setIdFranchisee(param.getIdFranchisee());
                } else {
                    throw new BusinessException(5002, "车队不属于此运力商");
                }
            }

            if (entity.getIdAgent() == null) {
                entity.setIdAgent(param.getIdAgent());
            } else if (entity.getIdAgent() != null &&
                    !entity.getIdAgent().equals(param.getIdAgent())) {
                if (StringUtil.isBlank(entity.getIdFranchisee())) {
                    entity.setIdAgent(param.getIdAgent());
                } else {
                    throw new BusinessException(5002, "车队不属于此服务商");
                }
            }
        }
        entity.setStatus(status);
        return fleetInforRepository.save(entity)!=null;
    }

    @Override
    public Boolean driverBindToggle(FleetBindDriverParam param) {
        DriverEntity find = driverRepository.findByIdDriver(param.getIdDriver());
        if (find == null)
            throw new BusinessException(5002,"司机不存在，请核查");
        if (StrUtil.isEmpty(find.getIdFleet()))
            throw new BusinessException(5002,"此司机是别的车队司机，请解绑后方可绑定");
        else
            find.setIdFleet(param.getIdFleet());
        return driverRepository.save(find)!=null;
    }

    @Override
    public Boolean driverUnBindToggle(FleetBindDriverParam param) {
        DriverEntity find = driverRepository.findByIdDriver(param.getIdDriver());
        if (find == null)
            throw new BusinessException(5002,"司机不存在，请核查");
        if (StringUtil.isBlank(find.getIdFleet())) {
            find.setIdFleet(null);
        } else {
            if (!find.getIdFleet().equals(param.getIdFleet())) {
                throw new BusinessException(5002,"非本车队的司机不可解绑");
            } else {
                find.setIdFleet(null);
            }
        }
        return driverRepository.save(find)!=null;
    }

    @Override
    public Boolean driverBindByFranchisee(FleetBindDriverParam param) {
        return driverBind(param,true);
    }

    @Override
    public Boolean driverUnBindByFranchisee(FleetBindDriverParam param) {
        return driverBind(param,false);
    }

    @Override
    public FleetCommisionSelectVO commisionSelect(String idFleet) {
        return FleetConvertor.INSTANCE.convert(commisionRepository.findByIdFleet(idFleet));
    }

    @Override
    public String commisionSave(FleetCommisionSaveParam param) {
        FleetCommisionEntity entity;
        if (StrUtil.isNotEmpty(param.getIdFleetCommision())){
            entity=commisionRepository.findById(param.getIdFleetCommision()).orElse(null);
            if (entity==null)
                throw new BusinessException(5002,"编辑对象不存在");
            FleetConvertor.INSTANCE.covert(entity,param);
        }else {
            entity=newFleetCommisionEntity(param);
        }
        entity = commisionRepository.save(entity);
        return entity.getIdFleetCommision();
    }

    @Override
    public FleetCommisionSaveParam commisionSaveSelect(String idFleetCommision) {
        FleetCommisionSaveParam re = FleetConvertor.INSTANCE.convertSaveSelect(commisionRepository.findById(idFleetCommision).orElse(null));
        if (re==null)
            throw new BusinessException(5002,"编辑对象不存在");
        return re;
    }

    private FleetCommisionEntity newFleetCommisionEntity(FleetCommisionSaveParam param){
        FleetCommisionEntity fleetCommisionEntity = new FleetCommisionEntity();
        fleetCommisionEntity.setIdFleetCommision(param.getIdFleetCommision());
        fleetCommisionEntity.setIdFleet(param.getIdFleet());
        fleetCommisionEntity.setIdAgent(param.getIdAgent());
        fleetCommisionEntity.setIdFranchisee(param.getIdFranchisee());
        fleetCommisionEntity.setModule(param.getModule());
        fleetCommisionEntity.setCommisionType(param.getCommisionType());
        fleetCommisionEntity.setFleetCommision(param.getFleetCommision());
        fleetCommisionEntity.setMemo(param.getMemo());
//        fleetCommisionEntity.setCreateBy();
//        fleetCommisionEntity.setCreateTime();
//        fleetCommisionEntity.setUpdateBy();
//        fleetCommisionEntity.setUpdateTime();
        return fleetCommisionEntity;

    }

    private boolean driverBind(FleetBindDriverParam param, boolean bind) {
        DriverEntity find = driverRepository.findByIdDriver(param.getIdDriver());
        if (StrUtil.isEmpty(param.getIdFranchisee()))
            throw new BusinessException(5002,"运力商ID为空，无法操作");

        if (find == null)
            throw new BusinessException(5002,"司机不存在，请核查");
        if (StrUtil.isEmpty(find.getIdFranchisee())) {
            find.setIdFranchisee(param.getIdFranchisee());
        } else {
            if (!find.getIdFranchisee().equals(param.getIdFranchisee())) {
                throw new BusinessException(5002,"此司机非本运力商司机，不能操作");
            } else {
                String idFleet = bind ? param.getIdFleet() : null;
                find.setIdFleet(idFleet);
                if (bind) {
                    find.setIdAgent(param.getIdAgent());
                }
            }
        }
        return driverRepository.save(find)!=null;
    }

}
